/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pb138.jprvyd.gui.list;

import cz.muni.fi.pb138.jprvyd.*;
import cz.muni.fi.pb138.jprvyd.gui.Main;
import cz.muni.fi.pb138.jprvyd.gui.form.ContactForm;
import cz.muni.fi.pb138.jprvyd.gui.form.InvoiceForm;
import cz.muni.fi.pb138.jprvyd.gui.model.Contact_TableModel;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;

/**
 *
 * @author Jan
 */
public class ContactList extends javax.swing.JFrame {

    private InvoiceForm invoiceForm;
    Main mainFrame;
    public List<Contact> contacts;
    public int rowIndex;
    private SwingWorker swingWorker;
    private ContactManager contactManager;
    public final int REMOVE = 0;
    public final int ADD = 1;
    public final int EDIT = 2;

    /**
     * Creates new form ContactList
     */
    public ContactList() {
        this.contacts = new ArrayList<Contact>();
        this.invoiceForm = new InvoiceForm();
        this.rowIndex = -1;
        this.contactManager = new ContactManagerImpl();
        initComponents();
    }

    public ContactList(InvoiceForm invoiceForm) {
        this.contactManager = new ContactManagerImpl();
        this.contacts = contactManager.getAllContacts();
        this.invoiceForm = invoiceForm;
        this.rowIndex = -1;
        initComponents();
    }

    public ContactList(Main mainFrame) {
        this.contactManager = new ContactManagerImpl();
        this.contacts = contactManager.getAllContacts();
        this.mainFrame = mainFrame;
        this.rowIndex = -1;
        initComponents();
        buttonDeleteContact.setEnabled(false);
        buttonEditContact.setEnabled(false);
        buttonNewContact.setEnabled(false);
    }

    private class editSwingWorker extends SwingWorker<Integer, Void> {

        ContactList list;

        public editSwingWorker(ContactList list) {
            this.list = list;
        }

        @Override
        protected Integer doInBackground() throws Exception {
            rowIndex = tableContacts.getSelectedRow();
            Contact_TableModel model = (Contact_TableModel) tableContacts.getModel();
            Integer contactICO = (Integer) model.getValueAt(rowIndex, 2);
            Contact contact = contactManager.getContactByIco(contactICO);
            ContactForm contactForm = new ContactForm(list, contact);
            contactForm.setVisible(true);
            return 0;
        }

        @Override
        protected void done() {
            swingWorker = null;
        }
    }

    private class deleteSwingWorker extends SwingWorker<Integer, Void> {

        @Override
        protected Integer doInBackground() throws Exception {
            Contact_TableModel model = (Contact_TableModel) tableContacts.getModel();
            Integer contactICO = (Integer) model.getValueAt(rowIndex, 2);
            Contact contact = contactManager.getContactByIco(contactICO);
            Long contactID = contact.getId();
            boolean ok = true;
            InvoiceManager invoiceManager = new InvoiceManagerImpl();
            List<Invoice> invoices = invoiceManager.getAllInvoices();
            for (Invoice invoice : invoices) {
                if (invoice.getContact().getId().equals(contactID)) {
                    ok = false;
                }
            }
            if (ok) {
                contactManager.removeContact(contactID);
                refreshContacts(contacts.get(rowIndex), REMOVE);
            } else {
                JOptionPane.showMessageDialog(rootPane, "Contact is tied to at least 1 invoice, can't be deleted");
            }
            return 0;
        }

        @Override
        protected void done() {
            swingWorker = null;
            buttonDeleteContact.setEnabled(true);
        }
    }

    private class selectSwingWorker extends SwingWorker<Integer, Void> {

        InvoiceForm invoiceForm;
        Main mainFrame;
        Integer contactICO;

        public selectSwingWorker(InvoiceForm invoiceForm, Integer contactICO) {
            this.contactICO = contactICO;
            this.invoiceForm = invoiceForm;

        }

        public selectSwingWorker(Main mainFrame, Integer contactICO) {
            this.contactICO = contactICO;
            this.mainFrame = mainFrame;

        }

        @Override
        protected Integer doInBackground() throws Exception {
            ContactManager contactManager = new ContactManagerImpl();
            Contact contact = contactManager.getContactByIco(contactICO);
            if (invoiceForm != null) {
                invoiceForm.contact = contact;
                invoiceForm.textFieldContact.setText(contact.getFirstName() + " " + contact.getSurname());
            } else if (mainFrame != null) {
                mainFrame.setContact(contact);
            }
            return 0;
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        tableContacts = new javax.swing.JTable();
        buttonNewContact = new javax.swing.JButton();
        buttonEditContact = new javax.swing.JButton();
        buttonDeleteContact = new javax.swing.JButton();
        buttonSelect = new javax.swing.JButton();
        buttonCancel = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("JPrVyd - Managing contacts");

        tableContacts.setModel(new Contact_TableModel(contacts)     );
        tableContacts.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                tableContactsMouseClicked(evt);
            }
        });
        jScrollPane1.setViewportView(tableContacts);

        buttonNewContact.setText("New contact");
        buttonNewContact.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonNewContactActionPerformed(evt);
            }
        });

        buttonEditContact.setText("Edit contact");
        buttonEditContact.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonEditContactActionPerformed(evt);
            }
        });

        buttonDeleteContact.setText("Delete contact");
        buttonDeleteContact.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonDeleteContactActionPerformed(evt);
            }
        });

        buttonSelect.setText("Select");
        buttonSelect.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonSelectActionPerformed(evt);
            }
        });

        buttonCancel.setText("Cancel");
        buttonCancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonCancelActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(10, 10, 10)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 375, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(10, 12, Short.MAX_VALUE))
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(buttonNewContact)
                        .addGap(41, 41, 41)
                        .addComponent(buttonEditContact)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(buttonDeleteContact))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(buttonSelect)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(buttonCancel)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 265, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(buttonEditContact)
                    .addComponent(buttonDeleteContact)
                    .addComponent(buttonNewContact))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(buttonSelect)
                    .addComponent(buttonCancel))
                .addGap(0, 11, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void buttonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonCancelActionPerformed
        this.dispose();
    }//GEN-LAST:event_buttonCancelActionPerformed

    private void buttonNewContactActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonNewContactActionPerformed
        ContactForm contactForm = new ContactForm(this);
        contactForm.setVisible(true);
    }//GEN-LAST:event_buttonNewContactActionPerformed

    private void buttonDeleteContactActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonDeleteContactActionPerformed
        rowIndex = tableContacts.getSelectedRow();
        if (rowIndex == -1) {
            JOptionPane.showMessageDialog(rootPane, "No contact selected");
        } else {
            int choice = JOptionPane.showConfirmDialog(rootPane, "Delete contact?", null, JOptionPane.YES_NO_OPTION);
            if (choice == 0) {
                if (swingWorker != null) {
                    throw new IllegalStateException("Operation in progress");
                }
                buttonDeleteContact.setEnabled(false);
                swingWorker = new deleteSwingWorker();
                swingWorker.execute();
            }
        }
    }//GEN-LAST:event_buttonDeleteContactActionPerformed

    private void tableContactsMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tableContactsMouseClicked
        if (rowIndex == tableContacts.getSelectedRow()) {
            this.buttonSelectActionPerformed(null);
        } else {
            rowIndex = tableContacts.getSelectedRow();
        }
    }//GEN-LAST:event_tableContactsMouseClicked

    private void buttonEditContactActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonEditContactActionPerformed
        rowIndex = tableContacts.getSelectedRow();
        if (rowIndex == -1) {
            JOptionPane.showMessageDialog(rootPane, "No contact selected");
        } else {
            if (swingWorker != null) {
                throw new IllegalStateException("Operation in progress");
            }
            swingWorker = new editSwingWorker(this);
            swingWorker.execute();
        }
    }//GEN-LAST:event_buttonEditContactActionPerformed

    private void buttonSelectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonSelectActionPerformed
        rowIndex = tableContacts.getSelectedRow();
        if (rowIndex == -1) {
            JOptionPane.showMessageDialog(rootPane, "No contact selected");
        } else {
            if (swingWorker != null) {
                throw new IllegalStateException("Operation in progress");
            }
            buttonSelect.setEnabled(false);
            Contact_TableModel model = (Contact_TableModel) tableContacts.getModel();
            Integer contactICO = (Integer) model.getValueAt(rowIndex, 2);
            if (invoiceForm != null) {
                swingWorker = new selectSwingWorker(this.invoiceForm, contactICO);
                swingWorker.execute();
            } else if (mainFrame != null) {
                swingWorker = new selectSwingWorker(mainFrame, contactICO);
                swingWorker.execute();
            }

            this.dispose();
        }
    }//GEN-LAST:event_buttonSelectActionPerformed

    public void refreshContacts(Contact contact, int operation) {
        if (operation == REMOVE) {
            contacts.remove(contact);
        } else if (operation == ADD) {
            contacts.add(contact);
        } else if (operation == EDIT) {
            contacts.set(rowIndex, contact);
        } else {
            throw new IllegalArgumentException("Wrong operation. Allowed operations are REMOVE (0), ADD (1), EDIT (2)");
        }
        tableContacts.updateUI();
        rowIndex = -1;
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /*
         * Set the Nimbus look and feel
         */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /*
         * If Nimbus (introduced in Java SE 6) is not available, stay with the
         * default look and feel. For details see
         * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(ContactList.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(ContactList.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(ContactList.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(ContactList.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /*
         * Create and display the form
         */
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new ContactList().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton buttonCancel;
    private javax.swing.JButton buttonDeleteContact;
    private javax.swing.JButton buttonEditContact;
    private javax.swing.JButton buttonNewContact;
    private javax.swing.JButton buttonSelect;
    private javax.swing.JScrollPane jScrollPane1;
    public javax.swing.JTable tableContacts;
    // End of variables declaration//GEN-END:variables
}
